<template>
  <div>
    <t-modal
      title="构件查询"
      width="900px"
      :visible="visible"
      @cancel="closeModal()"
      :wrapClassName="
        showResult
          ? 'component-search-container hide-footer'
          : 'component-search-container'
      "
      forceRender
    >
      <!-- 查询条件区域 -->
      <div class="search-warp" v-if="!showResult">
        <div class="component-search-modal-body">
          <a-form-model
            ref="ruleForm"
            :model="form"
            :rules="rules"
            :label-col="labelCol"
            :wrapper-col="wrapperCol"
          >
            <!-- 查询范围 -->
            <a-form-model-item
              ref="dataSetId"
              label="查询范围"
              prop="dataSetId"
            >
              <a-tree-select
                v-model="form.dataSetId"
                treeNodeFilterProp="title"
                show-search
                style="width: 100%"
                :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                placeholder="请选择"
                searchPlaceholder="请输入"
                tree-default-expand-all
                :replaceFields="{
                  children: 'subNodes',
                  title: 'nodeName',
                  key: 'dataSetId',
                  value: 'dataSetId',
                }"
                :tree-data="treeData"
              >
              </a-tree-select>
            </a-form-model-item>
            <!-- 构件名称 -->
            <a-form-model-item ref="desc" label="构件名称" prop="desc">
              <div class="form-item-warp">
                <a-select v-model="form.elemNamePredicate" style="width: 90px;">
                  <a-select-option :value="0">
                    等于
                  </a-select-option>
                  <a-select-option :value="1">
                    包含
                  </a-select-option>
                </a-select>
                <a-input v-model="form.elemName" placeholder="请输入构件名称" />
              </div>
            </a-form-model-item>
            <!--  添加属性查询条件-->
            <a-form-model-item>
              <div
                class="add-condition-button"
                :class="this.form.params.length == 3 && 'dis'"
                @click="addCondition()"
              >
                + 添加属性查询条件
              </div>
            </a-form-model-item>
            <!-- 新增查询条件列表 -->
            <div
              class="new-condition-form-item-warp"
              v-for="(domain, index) in form.params"
              :key="index"
            >
              <!-- 属性名称 -->
              <a-form-model-item
                :prop="'params.' + index + '.paramName'"
                :rules="{
                  required: true,
                  message: '请输入属性名称',
                  trigger: ['blur', 'change'],
                }"
              >
                <a-input
                  placeholder="请输入属性名称"
                  v-model="domain.paramName"
                />
              </a-form-model-item>
              <!-- 条件 -->
              <a-form-model-item
                :prop="'params.' + index + '.paramValuePredicate'"
                :rules="{
                  required: true,
                  message: '请输入属性名称',
                  trigger: 'change',
                }"
              >
                <a-select
                  style="width: 90px;flex-shrink:0;margin:0 10px"
                  v-model="domain.paramValuePredicate"
                >
                  <a-select-option :value="0">
                    等于
                  </a-select-option>
                  <a-select-option :value="1">
                    包含
                  </a-select-option>
                </a-select>
              </a-form-model-item>
              <!-- 属性值 -->
              <a-form-model-item
                :prop="'params.' + index + '.paramValue'"
                :rules="{
                  required: true,
                  message: '请输入属性名称',
                  trigger: ['blur', 'change'],
                }"
              >
                <a-input
                  placeholder="请输入属性值"
                  v-model="domain.paramValue"
                />
              </a-form-model-item>
              <a-icon type="delete" @click="deleteNewCondition(index)" />
            </div>
          </a-form-model>
        </div>
      </div>
      <template slot="footer" v-if="!showResult">
        <a-button
          type="primary"
          :loading="tableLoading"
          @click="handleSearch()"
        >
          查询
        </a-button>
      </template>
      <!-- 查询结果区域 -->
      <div class="search-result-warp" v-if="showResult">
        <div class="result-header">
          <div class="left">
            <icon-font type="icon-fanhui" @click="backSearch()"></icon-font>
            共检出{{ pager.total || 0 }}条数据
          </div>
          <div class="right">已选中{{ tableCheckRecords.length }}条数据</div>
        </div>
        <div class="result-body">
          <vxe-table
            ref="xTable"
            height="99%"
            align="center"
            show-overflow
            show-header-overflow
            border="inner"
            :data="tableData"
            :column-config="{ resizable: true }"
            size="small"
            :loading="tableLoading"
            @checkbox-all="selectAllEvent"
            @checkbox-change="selectChangeEvent"
            @cell-mouseenter="handleCellMouseEnter"
            @cell-mouseleave="handleCellMouseLeave"
          >
            <vxe-table-column type="checkbox" width="60"></vxe-table-column>
            <vxe-column title="ID" field="elemId" width="120"> </vxe-column>
            <vxe-column field="elemName" title="名称" width="200" show-overflow>
            </vxe-column>
            <vxe-column field="hostFileName" title="模型文件" show-overflow>
            </vxe-column>
            <vxe-column field="location" width="80">
              <template #default="{ row }">
                <icon-font
                  type="icon-27"
                  class="location-button"
                  @click="locationElemId(row)"
                  v-if="mouseEnterElemId == row.elemId"
                ></icon-font>
              </template>
            </vxe-column>
          </vxe-table>
        </div>
        <div class="result-footer">
          <a-button
            :disabled="tableCheckRecords.length == 0"
            @click="locationAllChoose()"
            >定位已选</a-button
          >
          <vxe-pager
            size="small"
            background
            :current-page.sync="pager.page"
            :page-size.sync="pager.pageSize"
            :total="pager.total"
            :layouts="['PrevPage', 'JumpNumber', 'NextPage', 'Sizes']"
            :page-sizes="[20, 50, 100, 500]"
            @page-change="paginationChange"
          >
            <template #left>
              <div class="vxe-pager-left-tip-container">
                共<span>{{ pager.total }}</span
                >条
              </div>
            </template>
          </vxe-pager>
        </div>
      </div>
    </t-modal>
  </div>
</template>

<script>
import { axios } from "@/utils/request";
import { Icon } from "ant-design-vue";
import { getModalTreeById } from "@/api/bim";
import { addAttributeByKey } from "@/utils/util.js";
import iconfrontjs from "@/assets/IconFont/iconfont.js";
const iconFrontUrl = iconfrontjs;
const IconFont = Icon.createFromIconfontCN({
  scriptUrl: iconFrontUrl,
});
export default {
  name: "componentSearchModal",
  inject: ["currentProject", "sceneSource"],
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
  },
  components: { IconFont },
  data() {
    return {
      treeData: [],
      tableData: [],
      mouseEnterElemId: "",
      tableCheckRecords: [],
      pager: {
        page: 1,
        pageSize: 20,
        total: 0,
      },
      showResult: false,
      tableLoading: false,
      loading: false,
      labelCol: { span: 4 },
      wrapperCol: { span: 18 },
      other: "",
      form: {
        //查询范围
        dataSetId: undefined,
        //构件名称
        elemName: "",
        elemNamePredicate: 0,
        params: [],
      },
      rules: {
        dataSetId: [
          {
            required: true,
            message: "请选择构件查询范围",
            trigger: "change",
          },
        ],
      },
    };
  },
  watch: {
    visible: {
      handler(val) {
        if (val) {
          this.getTreeData();
        }
      },
      immediate: true,
    },
  },
  mounted() {},
  methods: {
    //查询
    handleSearch() {
      this.$refs.ruleForm.validate((valid) => {
        if (valid) {
          this.getData();
        } else {
          this.showResult = false;
          return false;
        }
      });
    },

    //查询列表数据
    getData() {
      let { dataSetId, elemName, elemNamePredicate, params } = this.form;
      let { page, pageSize } = this.pager;
      return new Promise((resolve, reject) => {
        this.tableLoading = true;
        axios
          .post(
            `/probusiness/blackHole3D/project/element/getElementsByParamsPaging?pageNo=${page}&pageSize=${pageSize}`,
            {
              // 返回条数
              maxResultCount: pageSize,
              // 跳过条数
              skipCount: (page - 1) * pageSize,
              // 数据集Id
              dataSetId,
              // 模型文件名称
              hostFileName: "",
              // 构件名称
              elemName,
              // 构件名称过滤是否模糊 0=相等 1=模糊
              elemNamePredicate,
              // 查询构件的过滤行为，0=所有构件，1=单构件，2=组合构件
              elemBehaviour: 0,
              //属性参数列表
              params,
              // 是否启用es查询 默认true （未支持也可打开）
              enableEs: true,
            },
            {
              headers: {
                "Content-Type": "application/json",
              },
            }
          )
          .then((res) => {
            let { data } = res;
            let { totalCount, items, errMsg } = data ?? {};
            if (errMsg) {
              this.$message.error(errMsg);
              return;
            }
            this.tableData = items ?? [];
            this.pager.total = totalCount ?? 0;
            let chooseIds = this.tableCheckRecords.map((v) => v.elemId);
            let chooseData = this.tableData.filter((v) =>
              chooseIds.includes(v.elemId)
            );
            this.showResult = true;
            this.$nextTick((_) => {
              setTimeout((_) => {
                this.$refs.xTable.setCheckboxRow(chooseData, true);
              }, 200);
            });
            resolve();
          })
          .catch((_) => {
            this.tableData = [];
            this.pager.total = 0;
            reject();
          })
          .finally((_) => {
            this.tableLoading = false;
          });
      });
    },

    //监听table全选
    selectAllEvent({ checked, records }) {
      let ids = this.tableData.map((v) => v.elemId);
      if (checked) {
        this.tableCheckRecords.push(...records);
        this.tableCheckRecords = this.uniqueBy(
          this.tableCheckRecords,
          "elemId"
        );
      } else {
        this.tableCheckRecords = this.tableCheckRecords.filter(
          (v) => !ids.includes(v.elemId)
        );
      }
    },

    //监听table复选框
    selectChangeEvent({ checked, records, row }) {
      let { elemId } = row;
      if (checked) {
        this.tableCheckRecords.push(...records);
        this.tableCheckRecords = this.uniqueBy(
          this.tableCheckRecords,
          "elemId"
        );
      } else {
        this.tableCheckRecords = this.tableCheckRecords.filter(
          (v) => elemId != v.elemId
        );
      }
    },

    //监听table鼠标移入事件
    handleCellMouseEnter({ row }) {
      let { elemId } = row;
      this.mouseEnterElemId = elemId;
    },

    handleCellMouseLeave() {
      this.mouseEnterElemId = "";
    },

    //定位已选
    locationAllChoose() {
      let { tableCheckRecords } = this;
      let ids = tableCheckRecords.map((v) => v.elemId);
      this.setCamLocateToElem(ids);
    },

    //定位到当前构件
    locationElemId(row = {}) {
      let { elemId } = row;
      this.setCamLocateToElem([elemId]);
    },

    //相机定位到指定构件
    setCamLocateToElem(elemIdList = []) {
      try {
        let { dataSetId } = this.form;
        if (elemIdList.length > 0) {
          var locIDList = [{ dataSetId, elemIdList: elemIdList ?? [] }];
          BlackHole3D.BIM.resetElemAttr(dataSetId, []);
          //定位
          BlackHole3D.Camera.setCamLocateToElem(
            locIDList,
            1,
            BlackHole3D.RECamDirEm.CAM_DIR_DEFAULT
          );
          //上色
          this.setElemColor(
            dataSetId,
            elemIdList ?? [],
            new BlackHole3D.REColor(255, 0, 0, 190)
          );
        }
      } catch (error) {}
    },

    //设置构建颜色
    setElemColor(dataSetId, elemIds = [], color) {
      try {
        var elemAttr = new BlackHole3D.REElemAttr();
        elemAttr.dataSetId = dataSetId;
        elemAttr.elemIdList = elemIds;
        elemAttr.elemClr = color;
        BlackHole3D.BIM.setElemAttr(elemAttr);
      } catch (error) {}
    },

    //查询树列表
    getTreeData() {
      return new Promise((resolve, reject) => {
        let { foreignUuid } = this.currentProject();
        if (!foreignUuid) {
          return;
        }
        getModalTreeById({ projId: foreignUuid })
          .then((res) => {
            let { data } = res;
            let tree = data?.subNodes ?? [];
            let filterData = addAttributeByKey(
              null,
              "scopedSlots",
              { icon: "custom" },
              tree,
              "subNodes"
            );
            this.treeData = filterData;
            resolve();
          })
          .catch((_) => {
            this.treeData = [];
            reject();
          });
      });
    },

    //返回查询
    backSearch() {
      this.showResult = false;
      this.tableData = [];
      this.pager = {
        page: 1,
        pageSize: 20,
        total: 0,
      };
    },

    //json数组去重
    uniqueBy(arr, key) {
      const unique = {};
      return arr.filter((item) => {
        if (!unique[item[key]]) {
          unique[item[key]] = true;
          return true;
        }
        return false;
      });
    },

    //监听分页切换
    paginationChange({ currentPage, pageSize }) {
      this.pager.page = currentPage;
      this.pager.pageSize = pageSize;
      this.getData();
    },

    //新增查询条件
    addCondition() {
      if (this.form.params.length >= 3) {
        return;
      }
      this.form.params.push({
        //属性名称
        paramName: "",
        //属性值
        paramValue: "",
        //属性值过滤是否模糊 0=相等 1=模糊
        paramValuePredicate: 0,
      });
    },

    //删除查询条件
    deleteNewCondition(index = 0) {
      this.form.params = this.form.params.filter((v, i) => i != index);
    },

    //重置表单
    resetForm() {
      try {
        let { dataSetId } = this.form;
        // BlackHole3D.BIM.resetElemAttr(dataSetId, []);
      } catch (error) {}
      this.$refs?.ruleForm?.resetFields();
      setTimeout((_) => {
        this.showResult = false;
        this.tableCheckRecords = [];
        this.tableData = [];
        this.form = {
          //查询范围
          radius: "",
          //构件名称
          elemName: "",
          elemNamePredicate: 0,
          params: [],
        };
      }, 500);
    },

    //日期校验
    validateTime(rule, value, callback) {
      console.log(value);
      callback(new Error("请选择结束拆模时间"));
      return;
      if (!value) {
      } else if (moment(value).isBefore(startTime)) {
        callback(new Error("结束时间不能早于开始时间"));
      } else {
        callback();
      }
    },

    //关闭
    closeModal(type = 0) {
      this.$emit("update:visible", false);
      this.$emit("close");
      this.resetForm();
    },
  },
};
</script>

<style lang="less" scoped>
/deep/.component-search-container {
  &.hide-footer {
    .ant-modal-body {
      padding: 0 14px !important;
    }
    .ant-modal-footer {
      display: none;
    }
  }
  .component-search-modal-body {
    .form-item-warp {
      width: 100%;
      height: 100%;
      display: flex;
      .ant-input {
        flex: 1;
        margin-left: 10px;
      }
    }
    .add-condition-button {
      display: flex;
      align-items: center;
      justify-content: center;
      color: #1677ff;
      font-size: 14px;
      width: 180px;
      height: 32px;
      background: #ffffff;
      border-radius: 4px;
      border: 1px dashed #1677ff;
      margin-left: 80px;
      cursor: pointer;
      &.dis {
        cursor: not-allowed;
        border-color: #d9d9d9;
        color: #bfbfbf;
      }
    }

    .new-condition-form-item-warp {
      display: flex;
      padding: 6px 0 0 77px;
      display: flex;
      width: 100%;
      box-sizing: border-box;
      .ant-form-item {
        &:nth-child(1),
        &:nth-child(3) {
          width: 306px;
        }
        .ant-form-item-control-wrapper {
          width: 100%;
        }
      }
      .anticon-delete {
        font-size: 20px;
        color: #ff2d2d;
        margin-left: 16px;
        cursor: pointer;
        margin-top: 8px;
      }
    }
  }
  .search-result-warp {
    height: 428px;
    display: flex;
    flex-direction: column;
    .result-header {
      flex-shrink: 0;
      height: 60px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-size: 14px;
      .left {
        .anticon {
          color: #1677ff;
          margin-right: 2px;
          font-size: 16px;
          cursor: pointer;
        }
      }
    }
    .result-body {
      flex: 1;
      .location-button {
        color: #1677ff;
        cursor: pointer;
        font-size: 17px;
      }
    }
    .result-footer {
      flex-shrink: 0;
      height: 80px;
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
  }
}
</style>
